package com.dux.commons.database.dao;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.dux.commons.database.DatabaseConfig;
import com.dux.commons.scripts.java.scriptmanager.ScriptManager;


/**
 * DAO管理类
 * @author 杜祥
 * @create 2013-7-4
 */
public class DAOManager 
{
	
	private static final Logger log					= Logger.getLogger(DAOManager.class);
	
	/**
	 * 注册的DAP
	 */
	private static final Map<String, DAO> daoMap 	= new HashMap<String, DAO>();//注册的DAO
	
	/**
	 * 脚本管理类
	 */
	private static ScriptManager scriptManager;
	
	
	/**
	 * 初始化DAO管理类
	 */
	public static void init()
	{
		
		try 
		{
			scriptManager = new ScriptManager();
			scriptManager.setGlobalClassListener(new DAOLoader());
			scriptManager.load(DatabaseConfig.DATABASE_SCRIPTCONTEXT_DESCRIPTOR);
		} 
		catch (Exception e) 
		{
			throw new Error("无法加载DAO脚本：" + DatabaseConfig.DATABASE_SCRIPTCONTEXT_DESCRIPTOR, e);
		}
		log.info("加载DAO实例数:" + daoMap.size());
	}
	
	
	/**
	 * 关闭时执行方法
	 */
	public static void shutdown()
	{
		scriptManager.shutdown();
		daoMap.clear();
		scriptManager = null;
	}
	
	/**
	 * 返回Class对应的DAO
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T extends DAO>T getDAO(Class<T> clazz) throws DAONotFoundException
	{
		DAO dao = daoMap.get(clazz.getName());
		
		if(dao == null)
		{
			StringBuilder builder = new StringBuilder("没有找到class:").append(clazz.getName());
			builder.append("对应的DAO.");
			log.error(builder.toString());
			throw new DAONotFoundException(builder.toString());
		}
		
		return (T) dao;
	}
	
	/**
	 * 注册DAO
	 * @param dao
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void registerDAO(Class<? extends DAO> daoClass) throws InstantiationException, IllegalAccessException
	{
		DAO dao = daoClass.newInstance();
		synchronized (DAOManager.class) 
		{
			DAO oldDAO = daoMap.get(dao.getClassName());
			if(oldDAO != null)
			{
				StringBuilder builder = new StringBuilder("DAO:").append(dao.getClassName()).append("已经存在,");
				builder.append("已经存在DAO:").append(oldDAO.getClass().getName());
				builder.append("准备加入DAO:").append(dao.getClass().getName());
				log.error(builder.toString());
				throw new DAOAlreadyRegisteredException(builder.toString());
			}
			else
			{
				daoMap.put(dao.getClassName(), dao);
				/*StringBuilder builder = new StringBuilder("registerDAO:");
				builder.append(dao.getClassName());
				log.info(builder.toString());*/
			}
		}
		if(log.isDebugEnabled())
			log.debug("DAO " + dao.getClassName() + " 注册成功.");
	}
	
	/**
	 * 注销DAO
	 * @param dao
	 */
	public static void unregisterDAO(Class<? extends DAO> daoClass)
	{
		synchronized (DAOManager.class) 
		{
			for(DAO dao : daoMap.values())
			{
				if(dao.getClass() == daoClass)
				{
					daoMap.remove(dao.getClassName());
					if(log.isDebugEnabled())
						log.debug("DAO " + dao.getClassName() + " 注销成功.");
					break;
				}
			}
		}
	}
	
	
	private DAOManager(){
		
	}
}
